//! 随机数工具模块
//! 
//! 对应Java中的AppRandomUtil类，提供各种随机数生成功能

use rand::{Rng, thread_rng};
use rand::seq::SliceRandom;

/// 字符集常量
pub const NUMBERS_AND_LETTERS: &str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
pub const NUMBERS: &str = "0123456789";
pub const LETTERS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
pub const CAPITAL_LETTERS: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
pub const LOWER_CASE_LETTERS: &str = "abcdefghijklmnopqrstuvwxyz";

/// 生成指定长度的随机字符串（包含数字和字母）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_numbers_and_letters;
/// 
/// let random_str = random_numbers_and_letters(10);
/// assert_eq!(random_str.len(), 10);
/// assert!(random_str.chars().all(|c| c.is_alphanumeric()));
/// ```
pub fn random_numbers_and_letters(length: usize) -> String {
    random_string(NUMBERS_AND_LETTERS, length)
}

/// 生成指定长度的随机数字字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_numbers;
/// 
/// let random_str = random_numbers(8);
/// assert_eq!(random_str.len(), 8);
/// assert!(random_str.chars().all(|c| c.is_ascii_digit()));
/// ```
pub fn random_numbers(length: usize) -> String {
    random_string(NUMBERS, length)
}

/// 生成指定长度的随机字母字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_letters;
/// 
/// let random_str = random_letters(6);
/// assert_eq!(random_str.len(), 6);
/// assert!(random_str.chars().all(|c| c.is_alphabetic()));
/// ```
pub fn random_letters(length: usize) -> String {
    random_string(LETTERS, length)
}

/// 生成指定长度的随机大写字母字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_capital_letters;
/// 
/// let random_str = random_capital_letters(5);
/// assert_eq!(random_str.len(), 5);
/// assert!(random_str.chars().all(|c| c.is_uppercase()));
/// ```
pub fn random_capital_letters(length: usize) -> String {
    random_string(CAPITAL_LETTERS, length)
}

/// 生成指定长度的随机小写字母字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_lowercase_letters;
/// 
/// let random_str = random_lowercase_letters(7);
/// assert_eq!(random_str.len(), 7);
/// assert!(random_str.chars().all(|c| c.is_lowercase()));
/// ```
pub fn random_lowercase_letters(length: usize) -> String {
    random_string(LOWER_CASE_LETTERS, length)
}

/// 从指定字符集中生成随机字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_string;
/// 
/// let charset = "ABC123";
/// let random_str = random_string(charset, 4);
/// assert_eq!(random_str.len(), 4);
/// assert!(random_str.chars().all(|c| charset.contains(c)));
/// ```
pub fn random_string(source: &str, length: usize) -> String {
    if source.is_empty() || length == 0 {
        return String::new();
    }
    
    let chars: Vec<char> = source.chars().collect();
    let mut rng = thread_rng();
    
    (0..length)
        .map(|_| chars[rng.gen_range(0..chars.len())])
        .collect()
}

/// 从字符数组中生成随机字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_string_from_chars;
/// 
/// let chars = vec!['A', 'B', 'C', '1', '2', '3'];
/// let random_str = random_string_from_chars(&chars, 5);
/// assert_eq!(random_str.len(), 5);
/// assert!(random_str.chars().all(|c| chars.contains(&c)));
/// ```
pub fn random_string_from_chars(source_chars: &[char], length: usize) -> String {
    if source_chars.is_empty() || length == 0 {
        return String::new();
    }
    
    let mut rng = thread_rng();
    
    (0..length)
        .map(|_| source_chars[rng.gen_range(0..source_chars.len())])
        .collect()
}

/// 生成0到max之间的随机整数（不包括max）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_int;
/// 
/// let random_num = random_int(100);
/// assert!(random_num < 100);
/// assert!(random_num >= 0);
/// ```
pub fn random_int(max: i32) -> i32 {
    random_int_range(0, max)
}

/// 生成min到max之间的随机整数（不包括max）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_int_range;
/// 
/// let random_num = random_int_range(10, 20);
/// assert!(random_num >= 10);
/// assert!(random_num < 20);
/// ```
pub fn random_int_range(min: i32, max: i32) -> i32 {
    if min > max {
        return 0;
    }
    if min == max {
        return min;
    }
    
    let mut rng = thread_rng();
    rng.gen_range(min..max)
}

/// 生成指定范围内的随机长整数
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_long_range;
/// 
/// let random_num = random_long_range(1000, 2000);
/// assert!(random_num >= 1000);
/// assert!(random_num < 2000);
/// ```
pub fn random_long_range(min: i64, max: i64) -> i64 {
    if min > max {
        return 0;
    }
    if min == max {
        return min;
    }
    
    let mut rng = thread_rng();
    rng.gen_range(min..max)
}

/// 生成指定范围内的随机浮点数
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_float_range;
/// 
/// let random_num = random_float_range(1.0, 2.0);
/// assert!(random_num >= 1.0);
/// assert!(random_num < 2.0);
/// ```
pub fn random_float_range(min: f64, max: f64) -> f64 {
    if min > max {
        return 0.0;
    }
    if min == max {
        return min;
    }
    
    let mut rng = thread_rng();
    rng.gen_range(min..max)
}

/// 生成随机布尔值
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_bool;
/// 
/// let random_bool = random_bool();
/// assert!(random_bool == true || random_bool == false);
/// ```
pub fn random_bool() -> bool {
    let mut rng = thread_rng();
    rng.gen_bool(0.5)
}

/// 根据概率生成布尔值
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_bool_with_probability;
/// 
/// let result = random_bool_with_probability(0.8); // 80%概率为true
/// assert!(result == true || result == false);
/// ```
pub fn random_bool_with_probability(probability: f64) -> bool {
    let mut rng = thread_rng();
    rng.gen_bool(probability.clamp(0.0, 1.0))
}

/// 打乱数组（使用默认洗牌次数）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::shuffle_array;
/// 
/// let mut array = vec![1, 2, 3, 4, 5];
/// let original = array.clone();
/// shuffle_array(&mut array);
/// 
/// // 数组长度不变，但顺序可能发生变化
/// assert_eq!(array.len(), original.len());
/// for item in &original {
///     assert!(array.contains(item));
/// }
/// ```
pub fn shuffle_array<T>(array: &mut [T]) -> bool {
    if array.is_empty() {
        return false;
    }
    
    let mut rng = thread_rng();
    array.shuffle(&mut rng);
    true
}

/// 打乱数组指定次数
/// 
/// # Examples
/// ```
/// use librarys::random_utils::shuffle_array_times;
/// 
/// let mut array = vec![1, 2, 3, 4, 5];
/// let result = shuffle_array_times(&mut array, 3);
/// assert!(result);
/// ```
pub fn shuffle_array_times<T>(array: &mut [T], shuffle_count: usize) -> bool {
    if array.is_empty() || shuffle_count == 0 {
        return false;
    }
    
    for _ in 0..shuffle_count {
        shuffle_array(array);
    }
    
    true
}

/// 从数组中随机选择指定数量的元素
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_sample;
/// 
/// let array = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/// let sample = random_sample(&array, 3);
/// assert_eq!(sample.len(), 3);
/// 
/// for item in &sample {
///     assert!(array.contains(item));
/// }
/// ```
pub fn random_sample<T: Clone>(array: &[T], count: usize) -> Vec<T> {
    if array.is_empty() || count == 0 {
        return Vec::new();
    }
    
    let actual_count = count.min(array.len());
    let mut rng = thread_rng();
    
    array.choose_multiple(&mut rng, actual_count).cloned().collect()
}

/// 从数组中随机选择一个元素
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_choice;
/// 
/// let array = vec!["apple", "banana", "cherry", "date"];
/// let choice = random_choice(&array);
/// 
/// if let Some(chosen) = choice {
///     assert!(array.contains(&chosen));
/// }
/// ```
pub fn random_choice<T: Clone>(array: &[T]) -> Option<T> {
    if array.is_empty() {
        return None;
    }
    
    let mut rng = thread_rng();
    array.choose(&mut rng).cloned()
}

/// 生成随机UUID字符串（不包含连字符）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_uuid;
/// 
/// let uuid = random_uuid();
/// assert_eq!(uuid.len(), 32);
/// assert!(!uuid.contains('-'));
/// assert!(uuid.chars().all(|c| c.is_ascii_hexdigit()));
/// ```
pub fn random_uuid() -> String {
    uuid::Uuid::new_v4().to_string().replace('-', "")
}

/// 生成带连字符的UUID字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_uuid_with_hyphens;
/// 
/// let uuid = random_uuid_with_hyphens();
/// assert_eq!(uuid.len(), 36);
/// assert_eq!(uuid.matches('-').count(), 4);
/// ```
pub fn random_uuid_with_hyphens() -> String {
    uuid::Uuid::new_v4().to_string()
}

/// 生成随机中文字符
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_chinese_char;
/// 
/// let chinese_char = random_chinese_char();
/// assert!(chinese_char >= '\u{4e00}' && chinese_char <= '\u{9fa5}');
/// ```
pub fn random_chinese_char() -> char {
    let mut rng = thread_rng();
    let code_point = rng.gen_range(0x4e00..=0x9fa5);
    char::from_u32(code_point).unwrap_or('中')
}

/// 生成随机中文字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_chinese_string;
/// 
/// let chinese_str = random_chinese_string(5);
/// assert_eq!(chinese_str.chars().count(), 5);
/// assert!(chinese_str.chars().all(|c| c >= '\u{4e00}' && c <= '\u{9fa5}'));
/// ```
pub fn random_chinese_string(length: usize) -> String {
    (0..length)
        .map(|_| random_chinese_char())
        .collect()
}

/// 生成随机十六进制字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_hex_string;
/// 
/// let hex_str = random_hex_string(8);
/// assert_eq!(hex_str.len(), 8);
/// assert!(hex_str.chars().all(|c| c.is_ascii_hexdigit()));
/// ```
pub fn random_hex_string(length: usize) -> String {
    random_string("0123456789abcdef", length)
}

/// 生成随机大写十六进制字符串
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_hex_string_uppercase;
/// 
/// let hex_str = random_hex_string_uppercase(6);
/// assert_eq!(hex_str.len(), 6);
/// assert!(hex_str.chars().all(|c| "0123456789ABCDEF".contains(c)));
/// ```
pub fn random_hex_string_uppercase(length: usize) -> String {
    random_string("0123456789ABCDEF", length)
}

/// 权重随机选择
/// 
/// # Examples
/// ```
/// use librarys::random_utils::weighted_random_choice;
/// 
/// let items = vec!["A", "B", "C"];
/// let weights = vec![1.0, 2.0, 3.0]; // C的权重最高
/// 
/// let choice = weighted_random_choice(&items, &weights);
/// if let Some(chosen) = choice {
///     assert!(items.contains(&chosen));
/// }
/// ```
pub fn weighted_random_choice<T: Clone>(items: &[T], weights: &[f64]) -> Option<T> {
    if items.is_empty() || weights.is_empty() || items.len() != weights.len() {
        return None;
    }
    
    let total_weight: f64 = weights.iter().sum();
    if total_weight <= 0.0 {
        return None;
    }
    
    let mut rng = thread_rng();
    let random_value = rng.gen::<f64>() * total_weight;
    
    let mut cumulative_weight = 0.0;
    for (i, &weight) in weights.iter().enumerate() {
        cumulative_weight += weight;
        if random_value <= cumulative_weight {
            return Some(items[i].clone());
        }
    }
    
    // 如果由于浮点数精度问题没有选中，返回最后一个元素
    items.last().cloned()
}

/// 生成随机密码（包含大小写字母、数字和特殊字符）
/// 
/// # Examples
/// ```
/// use librarys::random_utils::random_password;
/// 
/// let password = random_password(12);
/// assert_eq!(password.len(), 12);
/// assert!(password.chars().any(|c| c.is_lowercase()));
/// assert!(password.chars().any(|c| c.is_uppercase()));
/// assert!(password.chars().any(|c| c.is_ascii_digit()));
/// ```
pub fn random_password(length: usize) -> String {
    if length < 4 {
        return random_string(NUMBERS_AND_LETTERS, length);
    }
    
    let lowercase = "abcdefghijklmnopqrstuvwxyz";
    let uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let digits = "0123456789";
    let special = "!@#$%^&*";
    
    let mut password = String::new();
    
    // 确保至少包含一个小写字母、大写字母、数字和特殊字符
    password.push_str(&random_string(lowercase, 1));
    password.push_str(&random_string(uppercase, 1));
    password.push_str(&random_string(digits, 1));
    password.push_str(&random_string(special, 1));
    
    // 填充剩余长度
    let all_chars = format!("{}{}{}{}", lowercase, uppercase, digits, special);
    password.push_str(&random_string(&all_chars, length - 4));
    
    // 打乱密码字符顺序
    let mut chars: Vec<char> = password.chars().collect();
    shuffle_array(&mut chars);
    
    chars.into_iter().collect()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_random_string_generation() {
        let random_str = random_numbers_and_letters(10);
        assert_eq!(random_str.len(), 10);
        assert!(random_str.chars().all(|c| NUMBERS_AND_LETTERS.contains(c)));
        
        let numbers = random_numbers(8);
        assert_eq!(numbers.len(), 8);
        assert!(numbers.chars().all(|c| c.is_ascii_digit()));
        
        let letters = random_letters(6);
        assert_eq!(letters.len(), 6);
        assert!(letters.chars().all(|c| c.is_alphabetic()));
        
        let capitals = random_capital_letters(5);
        assert_eq!(capitals.len(), 5);
        assert!(capitals.chars().all(|c| c.is_uppercase()));
        
        let lowercase = random_lowercase_letters(7);
        assert_eq!(lowercase.len(), 7);
        assert!(lowercase.chars().all(|c| c.is_lowercase()));
    }

    #[test]
    fn test_custom_random_string() {
        let charset = "ABC123";
        let random_str = random_string(charset, 10);
        assert_eq!(random_str.len(), 10);
        assert!(random_str.chars().all(|c| charset.contains(c)));
        
        // 测试空字符集
        assert_eq!(random_string("", 5), "");
        assert_eq!(random_string("ABC", 0), "");
    }

    #[test]
    fn test_random_integers() {
        let random_num = random_int(100);
        assert!(random_num >= 0 && random_num < 100);
        
        let range_num = random_int_range(10, 20);
        assert!(range_num >= 10 && range_num < 20);
        
        // 测试边界情况
        assert_eq!(random_int_range(5, 5), 5);
        assert_eq!(random_int_range(10, 5), 0); // min > max
    }

    #[test]
    fn test_random_floats() {
        let random_float = random_float_range(1.0, 2.0);
        assert!(random_float >= 1.0 && random_float < 2.0);
        
        // 测试边界情况
        assert_eq!(random_float_range(5.0, 5.0), 5.0);
        assert_eq!(random_float_range(10.0, 5.0), 0.0); // min > max
    }

    #[test]
    fn test_random_bool() {
        let bool_val = random_bool();
        assert!(bool_val == true || bool_val == false);
        
        // 测试概率
        let true_result = random_bool_with_probability(1.0);
        assert_eq!(true_result, true);
        
        let false_result = random_bool_with_probability(0.0);
        assert_eq!(false_result, false);
    }

    #[test]
    fn test_array_operations() {
        let mut array = vec![1, 2, 3, 4, 5];
        let original = array.clone();
        
        assert!(shuffle_array(&mut array));
        assert_eq!(array.len(), original.len());
        
        // 验证所有元素仍然存在
        for item in &original {
            assert!(array.contains(item));
        }
        
        // 测试空数组
        let mut empty: Vec<i32> = vec![];
        assert!(!shuffle_array(&mut empty));
    }

    #[test]
    fn test_random_sampling() {
        let array = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        
        let sample = random_sample(&array, 3);
        assert_eq!(sample.len(), 3);
        for item in &sample {
            assert!(array.contains(item));
        }
        
        // 测试选择超出数组长度的情况
        let large_sample = random_sample(&array, 15);
        assert_eq!(large_sample.len(), array.len());
        
        // 测试单个选择
        let choice = random_choice(&array);
        assert!(choice.is_some());
        assert!(array.contains(&choice.unwrap()));
        
        // 测试空数组
        let empty: Vec<i32> = vec![];
        assert!(random_choice(&empty).is_none());
    }

    #[test]
    fn test_uuid_generation() {
        let uuid = random_uuid();
        assert_eq!(uuid.len(), 32);
        assert!(!uuid.contains('-'));
        assert!(uuid.chars().all(|c| c.is_ascii_hexdigit()));
        
        let uuid_with_hyphens = random_uuid_with_hyphens();
        assert_eq!(uuid_with_hyphens.len(), 36);
        assert_eq!(uuid_with_hyphens.matches('-').count(), 4);
    }

    #[test]
    fn test_chinese_generation() {
        let chinese_char = random_chinese_char();
        assert!(chinese_char >= '\u{4e00}' && chinese_char <= '\u{9fa5}');
        
        let chinese_str = random_chinese_string(5);
        assert_eq!(chinese_str.chars().count(), 5);
        assert!(chinese_str.chars().all(|c| c >= '\u{4e00}' && c <= '\u{9fa5}'));
    }

    #[test]
    fn test_hex_generation() {
        let hex_str = random_hex_string(8);
        assert_eq!(hex_str.len(), 8);
        assert!(hex_str.chars().all(|c| c.is_ascii_hexdigit()));
        assert!(hex_str.chars().all(|c| c.is_lowercase() || c.is_ascii_digit()));
        
        let hex_upper = random_hex_string_uppercase(6);
        assert_eq!(hex_upper.len(), 6);
        assert!(hex_upper.chars().all(|c| "0123456789ABCDEF".contains(c)));
    }

    #[test]
    fn test_weighted_choice() {
        let items = vec!["A", "B", "C"];
        let weights = vec![1.0, 2.0, 3.0];
        
        let choice = weighted_random_choice(&items, &weights);
        assert!(choice.is_some());
        assert!(items.contains(&choice.unwrap()));
        
        // 测试无效权重
        let zero_weights = vec![0.0, 0.0, 0.0];
        assert!(weighted_random_choice(&items, &zero_weights).is_none());
        
        // 测试不匹配的长度
        let wrong_weights = vec![1.0, 2.0];
        assert!(weighted_random_choice(&items, &wrong_weights).is_none());
    }

    #[test]
    fn test_password_generation() {
        let password = random_password(12);
        assert_eq!(password.len(), 12);
        
        // 验证包含各种字符类型
        assert!(password.chars().any(|c| c.is_lowercase()));
        assert!(password.chars().any(|c| c.is_uppercase()));
        assert!(password.chars().any(|c| c.is_ascii_digit()));
        
        // 测试短密码
        let short_password = random_password(2);
        assert_eq!(short_password.len(), 2);
    }
}